package com.whfc.iot.session.impl;

import com.whfc.iot.session.Session;
import com.whfc.iot.session.SessionManager;
import io.netty.channel.Channel;

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2019/7/16 15:41
 */
public class SessionManagerImpl implements SessionManager {

    /**
     * channelId ==> session
     */
    private ConcurrentMap<String, Session> channelId2sessionMap;

    /**
     * deviceId -> channelId
     */
    private ConcurrentMap<String, String> sessionId2channelIdMap;

    public SessionManagerImpl(ConcurrentMap<String, Session> channelId2sessionMap, ConcurrentMap<String, String> sessionId2channelIdMap) {
        this.channelId2sessionMap = channelId2sessionMap;
        this.sessionId2channelIdMap = sessionId2channelIdMap;
    }

    @Override
    public Session createSession(Integer deviceType, Integer deviceId, Channel channel) {
        String channelId = channel.id().asLongText();
        String sessionId = String.valueOf(deviceId);
        Session session = new Session(sessionId);
        session.setChannel(channel);
        session.setDeviceType(deviceType);
        channelId2sessionMap.put(channelId, session);
        sessionId2channelIdMap.put(sessionId, channelId);
        return session;
    }

    @Override
    public Session createSession(Integer deviceType, String deviceSn, Channel channel) {
        String channelId = channel.id().asLongText();
        String sessionId = deviceSn;
        Session session = new Session(sessionId);
        session.setChannel(channel);
        session.setDeviceType(deviceType);
        channelId2sessionMap.put(channelId, session);
        sessionId2channelIdMap.put(sessionId, channelId);
        return session;
    }

    @Override
    public void delete(String channelId) {
        this.channelId2sessionMap.remove(channelId);
        Set<Map.Entry<String, String>> entrySet = this.sessionId2channelIdMap.entrySet();
        String sessionId = null;
        for (Map.Entry<String, String> entry : entrySet) {
            if (channelId.equals(entry.getValue())) {
                sessionId = entry.getKey();
            }
        }
        if (null != sessionId) {
            sessionId2channelIdMap.remove(sessionId, channelId);
        }
    }

    @Override
    public Session getSessionByDeviceId(Integer deviceId) {
        String sessionId = String.valueOf(deviceId);
        if (!sessionId2channelIdMap.containsKey(sessionId)) {
            return null;
        }
        String channelId = sessionId2channelIdMap.get(sessionId);
        return this.getSessionByChannelId(channelId);
    }

    @Override
    public Session getSessionByDeviceSn(String deviceSn) {
        String sessionId = deviceSn;
        if (!sessionId2channelIdMap.containsKey(sessionId)) {
            return null;
        }
        String channelId = sessionId2channelIdMap.get(sessionId);
        return this.getSessionByChannelId(channelId);
    }

    @Override
    public Session getSessionByChannelId(String channelId) {
        if (!channelId2sessionMap.containsKey(channelId)) {
            return null;
        }
        return channelId2sessionMap.get(channelId);
    }

    @Override
    public Map<String, String> getAllOnlineDevice() {
        return sessionId2channelIdMap;
    }


}
